package com.qinggeng.project.api.utils;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Maps;
import com.qinggeng.common.exception.CustomException;
import com.qinggeng.common.utils.StringUtils;
import com.qinggeng.common.utils.http.HttpUtils;
import com.qinggeng.project.system.domain.json.AddressComponent;
import org.apache.http.HttpResponse;
import org.apache.http.util.EntityUtils;
import org.bouncycastle.asn1.cms.PasswordRecipientInfo;
import org.redisson.MapWriterTask;

import java.util.Map;

public class AMapUtils {

    private static final String KEY = "1221c2d24416e9ed71ed0f28d77eb800";

    private static double EARTH_RADIUS = 6378.137;// 单位千米

    private static String REGEOCODE="regeocode";

    private static String ADDRESS_COMPONENT="addressComponent";

    private static String AMAP_REST_API_HOST="https://restapi.amap.com";

    private static String DISTANCE_PATH="/v3/distance";

    private static String GEOCODE_REGEO_PATH="/v3/geocode/regeo";

    /**
     * 计算二点距离
     *
     * @param origins     起点经纬度逗号分隔
     * @param destination 终点经纬度逗号分隔
     * @return
     */
    public static JSONObject distance(String origins, String destination) throws Exception {
        Map<String, String> querys = Maps.newHashMap();
        querys.put("origins", origins);
        querys.put("destination", destination);
        querys.put("key", KEY);
        querys.put("output", "json");
        HttpResponse httpResponse = HttpUtils.doGet(AMAP_REST_API_HOST, DISTANCE_PATH, null, querys);
        JSONObject jsonObject = JSON.parseObject(EntityUtils.toString(httpResponse.getEntity(), "UTF-8"));
        if (jsonObject.getInteger("status") != 1) {
            throw new CustomException("距离获取失败：" + jsonObject.getString("info"));
        }
        return jsonObject;
    }

    public static void main(String[] args) {
//        AMapUtils.distance("116.481028,39.989643", "114.465302,40.004717");
    }

    /**
     * 地址逆解析
     *
     * @param location
     * @return
     */
    public static JSONObject geocodeRegeo(String location) throws Exception {
        Map<String, String> querys = Maps.newHashMap();
        querys.put("location", location);
        querys.put("key", KEY);
        querys.put("output", "json");
        HttpResponse httpResponse = HttpUtils.doGet(AMAP_REST_API_HOST, GEOCODE_REGEO_PATH, null, querys);
        JSONObject jsonObject = JSON.parseObject(EntityUtils.toString(httpResponse.getEntity(), "UTF-8"));
        if (jsonObject.getInteger("status") != 1) {
            throw new CustomException("逆解析失败：" + jsonObject.getString("info"));
        }
        return jsonObject;
    }


    public static AddressComponent getAddressComponent(Float lng,Float lat){
        try {
            JSONObject object=geocodeRegeo(lng+","+lat);
            JSONObject regeocode=object.getObject(REGEOCODE,JSONObject.class);
            return regeocode.getObject(ADDRESS_COMPONENT,AddressComponent.class);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 根据经纬度获取地区名
     * @param lng
     * @param lat
     * @return
     */
    public static String getDistrict(Float lng,Float lat){
        AddressComponent addressComponent=getAddressComponent(lng,lat);
        if(null==addressComponent|| StringUtils.isEmpty(addressComponent.getDistrict())){
            return "";
        }
        return addressComponent.getDistrict();
    }





    /**
     * 依据经纬度计算两点之间的距离 GetDistance:(). <br/>
     *
     *
     * @author chiwei
     * @param lat1
     *            1点的纬度
     * @param lng1
     *            1点的经度
     * @param lat2
     *            2点的纬度
     * @param lng2
     *            2点的经度
     * @return 距离 单位 米
     * @since JDK 1.6
     */
    public static double getDistance(double lat1, double lng1, double lat2, double lng2) {
        double radLat1 = getRadian(lat1);
        double radLat2 = getRadian(lat2);
        double a = radLat1 - radLat2;// 两点纬度差
        double b = getRadian(lng1) - getRadian(lng2);// 两点的经度差
        double s = 2 * Math.asin(Math.sqrt(Math.pow(Math.sin(a / 2), 2) + Math.cos(radLat1)
                * Math.cos(radLat2) * Math.pow(Math.sin(b / 2), 2)));
        s = s * EARTH_RADIUS;
        return s * 1000;
    }

    /**
     * 角度弧度计算公式 rad:(). <br/>
     *
     * 360度=2π π=Math.PI
     *
     * x度 = x*π/360 弧度
     *
     * @author chiwei
     * @param
     * @return
     * @since JDK 1.6
     */
    private static double getRadian(double degree) {
        return degree * Math.PI / 180.0;
    }
}
